package com.en.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.en.mapper.ReviewMapper;
import com.en.model.Review;
import com.en.service.ReviewService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * @author wuhaitao
 * @description 针对表【review】的数据库操作Service实现
 * @createDate 2023-11-25 11:09:49
 */
@Service
public class ReviewServiceImpl extends ServiceImpl<ReviewMapper, Review>
        implements ReviewService {
    @Autowired
    ReviewMapper reviewMapper;

    @Override
    public Integer addWord(Integer word_id) {

        Review review = new Review();

        review.setWordId(word_id);
        review.setUserId(1);

        Integer res = reviewMapper.insert(review);
        return res;
    }


    @Override
    public Integer updateReview(Integer id, String is_right) {
        LambdaUpdateWrapper<Review> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Review::getId, id);
        updateWrapper.set(Review::getLastReviewTime, LocalDateTime.now());

        if ("true".equals(is_right)) {
            updateWrapper.setSql("right_times = right_times + 1");
        } else {
            updateWrapper.setSql("wrong_times = wrong_times + 1");
        }

        Integer res = reviewMapper.update(updateWrapper);
        System.out.println(updateWrapper);

        return res;
    }


    @Override
    public List<Review> getReview() {
        LambdaQueryWrapper<Review> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.eq(Review::getUserId, 1);

        List<Review> reviewList = reviewMapper.selectList(queryWrapper);


//        -------
//        for (Review review : reviewList) {
//            review.setRightTimes((int) (Math.random() * 10));
//            review.setWrongTimes((int) (Math.random() * 30));
//        }


        // 如果小于10则直接全部返回
        if (reviewList.size() < 20) {
            return reviewList;
        }

        // 先去掉近1小时已经复习过的
        LocalDateTime now = LocalDateTime.now();

//        Iterator<Review> iterator_review = reviewList.iterator();
//        while (iterator_review.hasNext()) {
//            Review review = iterator_review.next();
//            // 如果是30分钟内刚复习过，则直接删掉
//            if (review.getLastReviewTime().isAfter(now.minusMinutes(30))) {
//                iterator_review.remove();
//            }
//        }

        // 根据正确次数、错误次数、最近一次学习时间进行综合排序
        for (Review review : reviewList) {
            Integer rightTimes = review.getRightTimes();
            Integer wrongTimes = review.getWrongTimes();
            Integer allTimes = rightTimes + wrongTimes;


            Integer grade;
            double ratio = (double) rightTimes / (double) allTimes;

            if (allTimes == 0 || rightTimes == 0 || (allTimes >= 10 && rightTimes == 1) || (allTimes >= 30 && rightTimes == 2) || (allTimes >= 50 && rightTimes == 3) || (allTimes >= 70 && rightTimes == 4) || (allTimes >= 90 && rightTimes == 5) || (allTimes >= 110 && rightTimes == 6) || (allTimes >= 130 && rightTimes == 7) || (allTimes >= 150 && rightTimes == 8)) { //  没有复习过、没有正确过
                grade = 1;
            } else if ((allTimes > 5 && allTimes < 10 && rightTimes == 1) || ratio <= 0.1) {
                grade = 2;
            } else if (allTimes == 1 || (allTimes >= 3 && allTimes <= 5 && rightTimes == 1) || ratio <= 0.15) { // 复习1次，正确1次，因为如果错误1次则会跑到上面去
                grade = 3;
            } else if (ratio <= 0.2) {
                grade = 4;
            } else if (allTimes == 2 || (allTimes > 5 && rightTimes == 2) || (allTimes > 10 && ratio <= 0.25)) {
                grade = 5;
            } else if (ratio <= 0.3) {
                grade = 6;
            } else if (allTimes == 3 || (allTimes > 5 && rightTimes == 3) || (allTimes > 10 && ratio <= 0.35)) {
                grade = 7;
            } else if (allTimes == 4 || ratio <= 0.4) {
                grade = 8;
            } else if (allTimes == 5 || allTimes == 6 || (allTimes > 8 && rightTimes == 4) || ratio <= 0.45) {
                grade = 9;
            } else if (allTimes == 7 || allTimes == 8 || ratio <= 0.5) {
                grade = 10;
            } else if (allTimes == 9 || allTimes == 10 || ratio <= 0.55) {
                grade = 11;
            } else if (allTimes == 11 || allTimes == 12 || ratio <= 0.6) {
                grade = 12;
            } else if (allTimes == 13 || allTimes == 14 || ratio <= 0.65) {
                grade = 13;
            } else if (allTimes == 15 || allTimes == 16 || ratio <= 0.7) {
                grade = 14;
            } else if (allTimes == 17 || allTimes == 18 || ratio <= 0.75) {
                grade = 15;
            } else if (allTimes == 19 || allTimes == 20 || ratio <= 0.8) {
                grade = 16;
            } else if (ratio <= 0.85) {
                grade = 17;
            } else if (ratio <= 0.9) {
                grade = 18;
            } else if (ratio <= 0.91) {
                grade = 19;
            } else if (ratio <= 0.92) {
                grade = 20;
            } else if (ratio <= 0.93) {
                grade = 21;
            } else if (ratio <= 0.94) {
                grade = 22;
            } else if (ratio <= 0.95) {
                grade = 23;
            } else if (ratio <= 0.96) {
                grade = 24;
            } else if (ratio <= 0.97) {
                grade = 25;
            } else if (ratio <= 0.98) {
                grade = 26;
            } else if (ratio <= 0.99) {
                grade = 27;
            } else {
                grade = 28;
            }


            LocalDateTime lastReviewTime = review.getLastReviewTime();
            Duration duration = Duration.between(lastReviewTime, now);


            Integer x = (int) (grade / Math.sqrt(duration.getSeconds()) * 1000000);
            review.setX(x);
            review.setGrade(grade);

            review.setY((int) duration.getSeconds() / 3600);
        }


        Collections.sort(reviewList, new Comparator<Review>() {
            @Override
            public int compare(Review o1, Review o2) {
                return o1.getX() - o2.getX();
            }
        });

//        System.out.println("-------------------------------------");
//        for (Review review : reviewList) {
//            System.out.println("right:" + review.getRightTimes() + "; wrong:" + review.getWrongTimes() + "; grade:" + review.getGrade() + "; Y:" + review.getY() + "; X:" + review.getX());
//        }

        return reviewList;

    }
}




